<?php
class DatabaseObject_Image extends DatabaseObject {
	protected $album = null;
	protected $_uploadedFile;
	
	public function __construct($db) {
		parent::__construct($db, 'images', 'imageid');
		$this->add('albumid');
		$this->add('dateline');
		$this->add('filename');
		$this->add('introduce');
	}
	
	static public function GetUploadPath() {
		$config = Zend_Registry::get('config');
		return sprintf('%s/uploaded-images', $config->paths->data);
	}
	
	public function getFullPath() {
		return sprintf('%s/%d',self::GetUploadPath(), $this->getId());
	}
	
	public function uploadFile($path) {
		if (!file_exists($path) || !is_file($path)) {
			throw new Exception('无法找到文件');
		}
		
		if (!is_readable($path)) {
			throw new Exception('不能读取文件');
		}
		
		$this->_uploadedFile = $path;
	}
	
	public function preDelete() {
		unlink($this->getFullPath());
		$pattern = sprintf('%s/%d.*', self::GetThumbnailPath(), $this->getId());
		
		foreach (glob($pattern) as $thumbnail) {
			unlink($thumbnail);
		}
		return true;
	}
	public function preInsert() {
		$path = self::GetUploadPath();
		if (!file_exists($path) || !is_dir($path)) {
			throw new Exception('上传目录：'.$path.'不存在');
		}
		
		if (!is_writable($path)) {
			throw new Exception('目录：'.$path.'不能写入');
		}
		
		//TODO 载入图片等级
		return true;
	}
	
	public function postInsert() {
		if (strlen($this->_uploadedFile) > 0) {
			return move_uploaded_file($this->_uploadedFile, $this->getFullPath());
		}
		
		return false;
	}
	
	public function createThumbnail($maxW, $maxH) {
		$fullpath = $this->getFullPath();
		$time = (int) filemtime($fullpath);
		$info = getimagesize($fullpath);
		
		$w = $info[0];
		$h = $info[1];
		$ratio = $w / $h;
		$maxW = min($w, $maxW);
		if ($maxW == 0) {
			$maxW = $w;
		}
		
		$maxH = min($h, $maxH);
		if ($maxH == 0) {
			$maxH = $h;
		}
		
		$newW = $maxW;
		$newH = $newW / $ratio;
		
		if ($newH > $maxH) {
			$newH = $maxH;
			$newW = $newH * $ratio;
		}
		
		if ($w == $newW && $newH) {
			return $fullpath;
		}
		
		switch ($info[2]) {
			case IMAGETYPE_PNG  :
				$infunc = 'ImageCreateFromPng';
				$outfunc = 'ImagePng';
				break;
            case IMAGETYPE_GIF  :
            	$infunc = 'ImageCreateFromGif';
                $outfunc = 'ImageGif';
                break;
            case IMAGETYPE_JPEG :
            	$infunc = 'ImageCreateFromJpeg';
                $outfunc = 'ImageJpeg';
                break;
            default:
            	throw new Exception('非法图形格式');
		}
		
		$filename = sprintf('%d.%dx%d.%d', $this->getId(), $newW, $newH, $time);
		$path = self::GetThumbnailPath();
		
		if (!file_exists($path)) {
			mkdir($path, 0777);
		}
		
		if (!is_writable($path)) {
			throw new Exception('无法写入文件');
		}
		
		$thumbPath = sprintf('%s/%s', $path, $filename);
		
		if (!file_exists($thumbPath)) {
			$im = @$infunc($fullpath);
			if (!$im) {
				throw new Exception('不能读取图像文件');
			}
			
			$thumb = imagecreatetruecolor($newW, $newH);
            imagecopyresampled($thumb, $im, 0, 0, 0, 0, $newW, $newH, $w, $h);
            $outfunc($thumb, $thumbPath);
		}
		
		if (!file_exists($thumbPath)) {
			throw new Exception('创建缩略图时产生未知错误');
		}
		if (!is_readable($thumbPath)) {
			throw new Exception('不能读取缩略图');
		}
		
		return $thumbPath;
	}
	
	static public function GetImageHash($id, $w, $h) {
		$id = (int) $id;
		$w  = (int) $w;
		$h  = (int) $h;
		
		return md5(sprintf('%s,%s,%s', $id, $w, $h));
	}
	static public function GetThumbnailPath() {
		$config = Zend_Registry::get('config');
		return sprintf('%s/tmp/thumbnails', $config->paths->data);
	}
    static public function _GetBaseQuery($db, $options) {
        $defaults = array('albumid' => array(),
                          'from'   => '',
                          'to'     => '');
        
        foreach ($defaults as $k => $v) {
            $options[$k] = array_key_exists($k, $options) ? $options[$k] : $v;
        }
        
        $select = $db->select();
        $select->from(array('i' => 'images'), array());
        
        if (strlen($options['from']) > 0) {
            $select->where('i.dateline <= ?', $options['from']);
        }
        
        if (strlen($options['to']) > 0) {
            $select->where('i.dateline >= ?', $options['to']);
        }
        
        if (count($options['albumid']) > 0) {
            $select->where('i.albumid in (?)', $options['albumid']);
        }
        return $select;
    }
    static public function GetImageCount($db, $options) {
        $select = self::_GetBaseQuery($db, $options);
        $select->from(null, 'count(*)');
        return $db->fetchOne($select);
    }
    
    static public function GetImages($db, $options = array()) {
        $defaults = array('offset'  => 0,
                          'limit'   => 0,
                          'order'   => 'i.dateline');
        
        foreach ($defaults as $k => $v) {
            $options[$k] = array_key_exists($k, $options) ? $options[$k] : $v;
        }
        
        $select = self::_GetBaseQuery($db, $options);
        $select->from(null, 'i.*');
        
        if ($options['limit'] > 0) {
            $select->limit($options['limit'], $option['offset']);
        }
        
        $select->order($options['order']);
        
        $data = $db->fetchAll($select);
        $albums = self::BuildMultiple($db, __CLASS__, $data);
        $albumids = array_keys($albums);
        if (count($albumids) == 0) {
            return array();
        }

        return $albums;
    }
}
?>